package com.cmit.upay.monitor.service.impl;

import com.cmit.upay.monitor.service.WriteDataService;
import com.cmit.upay.monitor.vo.QueueVO;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

/**
 * <br/>
 *
 * @author liyuanchang
 * @version V1.0
 * @email liyuanchang@chinamobile.com
 * @date 2020-03-12 11:17
 */
@Slf4j
public abstract class AbstractWriteDataToFileService implements WriteDataService {
    /** 写文件的目录 */
    protected String dir;
    /** 当前要写的文件 */
    protected String filename;
    /** 已写行数计数器 */
    protected int fileLines;
    /** 单个文件最大行数，超过就写新文件 */
    protected int pageSize;

    public AbstractWriteDataToFileService(String dir, int pageSize) {
        this.dir = dir;
        this.pageSize = pageSize;
        createNewFile();
    }

    @Override
    public void write(List<QueueVO> list) {
        if (log.isDebugEnabled()) {
            log.debug("开始写入数据，当前写入文件{}", filename);
        }
        if (fileLines > pageSize) {
            // 创建新文件
            createNewFile();
        }
        QueueVO currentData = null;
        try {
            // 写入数据，即使超出阈值也将同一批文件写入到同一个文件里
            for (QueueVO data : list) {
                currentData = data;
                // 调用子类方法
                write(currentData);
                fileLines++;
                if (log.isDebugEnabled()) {
                    log.debug("写入数据{}完成", currentData);
                }
            }
            flushData();
        } catch (Exception e) {
            String errorMsg = String.format("写数据%s过程出错。", currentData);
            log.error(errorMsg, e);
        }
    }

    /**
     * 写入单条数据
     * @param data
     */
    protected abstract void write(QueueVO data);

    /**
     * 重置文件行数计数器
     * @return 返回之前已写行数
     */
    public int resetFileLines() {
        int oldValue = fileLines;
        fileLines = 0;
        return oldValue;
    }

    /**
     * 创建一个新文件
     * @param
     */
    public abstract void createNewFile();

    /**
     * 强制写入
     */
    public abstract void flushData();

    public void setFileLines(int fileLines) {
        this.fileLines = fileLines;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }
}
